package cn.yy.tool;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

@Resource(name="template")
public class RedisTemplateUtil {

	public RedisTemplateUtil(){
		
	}
	
	@Autowired
	private RedisTemplate<String,Object> redisTemplate;  
	 
	
	
	
	//=================common================
	  
	public RedisTemplate<String, Object> getRedisTemplate() {
		return redisTemplate;
	}

	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	/**
	 * 指定缓存失效时间
	 * @param key
	 * @param time
	 * @return
	 */
    public boolean expire(String key,long time){
    	try {
			if(time>0){
				redisTemplate.expire(key, time, TimeUnit.SECONDS);
			}
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 根据Key获取过期时间
     * @param key
     * @return
     */
    public long getExpire(String key){
    	return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    
    /**
     * 判断key是否存在
     * @param key
     * @return
     */
    public boolean hasKey(String key){
    	try {
			return redisTemplate.hasKey(key);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 删除缓存
     * @param keys
     */
    @SuppressWarnings("unchecked")
	public void delete(String...keys){
    	if(keys!=null&&keys.length>0){
    		if(keys.length==1){
    			redisTemplate.delete(keys[0]);
    		}else{
    			redisTemplate.delete(CollectionUtils.arrayToList(keys));
    		}
    	}
    }
    //=============string====================
    
    /**
     * 普通方式获取缓存
     * @param key
     * @return
     */
    public Object get(String key){
    	return key==null?null:redisTemplate.opsForValue().get(key);
    }
    
    /**
     * 普通方式放入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean set(String key,Object value){
    	try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 普通放入缓存并设置时间
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean set(String key,Object value,long time){
    	try {
			if(time>0){
				redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
			}else{
				set(key,value);
			}
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 递增
     * @param key
     * @param delta增加多少
     * @return
     */
    public long incr(String key,long delta){
    	if(delta<0){
    		throw new RuntimeException("递增因子必需大于0");
    	}
    	return redisTemplate.opsForValue().increment(key, delta);
    }
    
    /**
     * 递减
     * @param key
     * @param delta减少多少
     * @return
     */
    public long decr(String key,long delta){
    	if(delta<0){
    		throw new RuntimeException("递减因子必需大于0");
    	}
    	return redisTemplate.opsForValue().increment(key, -delta);
    }
    
    //===========map================================
    /**
     * HashGet
     * @param key
     * @param item
     * @return
     */
    public Object hashGet(String key,String item){
    	return redisTemplate.opsForHash().get(key, item);
    }
    
    /**
     * 获取hashKey对应的所有键值
     * @param key
     * @return
     */
    public Map<Object,Object> hashAndMapGet(String key){
    	return redisTemplate.opsForHash().entries(key);
    }
    
    /**
     * HashSet
     * @param key
     * @param map
     * @return
     */
    public boolean hashAndMapSet(String key,Map<Object,Object> map){
    	try {
			redisTemplate.opsForHash().putAll(key, map);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * HashSet并设置时间
     * @param key
     * @param map
     * @param time
     * @return
     */
    public boolean hashAndMapSet(String key,Map<Object,Object> map,long time){
    	try {
			redisTemplate.opsForHash().putAll(key, map);
			if(time>0){
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 向一张hash表放入数据，如果不存在将创建
     * @param key
     * @param item
     * @param value
     * @return
     */
    public boolean hashSet(String key,String item,Object value){
    	try {
			redisTemplate.opsForHash().put(key, item, value);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 向一张hash表放入数据，如果不存在将创建,若果已存在的hash表有时间这里的将会替换原来的时间s
     * @param key
     * @param item
     * @param value
     * @param time
     * @return
     */
    public boolean hashSet(String key,String item,Object value,long time){
    	try {
			redisTemplate.opsForHash().put(key, item, value);
			if(time>0){
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 删除hash表中值
     * @param key
     * @param items
     */
    public void hashDelete(String key,Object...items){
    	redisTemplate.opsForHash().delete(key, items);
    }
    
    /**
     * 判断hash表中是否有该项的值
     * @param key
     * @param item
     * @return
     */
    public boolean hashHasKey(String key,String item){
    	return redisTemplate.opsForHash().hasKey(key, item);
    }
    
    /**
     * hash递增 如果不存在就好创建一个并把新的值返回
     * @param key
     * @param item
     * @param by要增加多少
     * @return
     */
    public double hashIncr(String key,String item,double by){
    	return redisTemplate.opsForHash().increment(key, item, by);
    }
    
    /**
     * hash递减 
     * @param key
     * @param item
     * @param by要减少多少
     * @return
     */
    public double hashDecr(String key,String item,double by){
    	return redisTemplate.opsForHash().increment(key, item, -by);
    }
    
    //================set============================
    /**
     * 根据Key获取set中的所有值
     * @param key
     * @return
     */
    public Set<Object> setGet(String key){
    	try {
			return redisTemplate.opsForSet().members(key);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
    }
    
    /**
     * 根据value从一个set中查询是否存在
     * @param key
     * @param value
     * @return
     */
    public boolean setHasKey(String key,Object value){
    	try {
			return redisTemplate.opsForSet().isMember(key, value);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 将数据放入set缓存
     * @param key
     * @param values
     * @return
     */
    public long setSet(String key,Object...values){
    	try {
			return redisTemplate.opsForSet().add(key, values);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
    }
    
    /**
     * 把set数据放入缓存
     * @param key
     * @param time
     * @param values
     * @return
     */
    public long setSet(String key,long time,Object...values){
    	try {
			Long count= redisTemplate.opsForSet().add(key, values);
			if(time>0){
				expire(key, time);
			}
			return count;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
    }
    
    /**
     * 获取set缓存的长度
     * @param key
     * @return
     */
    public long setGetSetSize(String key){
    	try {
			return redisTemplate.opsForSet().size(key);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
    }
    
    /**
     * 移除值为value的key
     * @param key
     * @param values
     * @return
     */
    public long setRemove(String key,Object...values){
    	try {
			Long count=redisTemplate.opsForSet().remove(key, values);
			return count;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
    }
    
    //==============list================================
    /**
     * 获取list缓存的内容
     * @param key
     * @param start
     * @param end
     * @return
     */
    public List<Object> listGet(String key,long start,long end){
    	try {
			return redisTemplate.opsForList().range(key, start, end);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
    }
    
    /**
     * 获取list缓存的长度
     * @param key
     * @return
     */
    public long listGetSize(String key){
    	try {
			return redisTemplate.opsForList().size(key);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
    }
    
    /**
     * 通过索引获取list中的值
     * @param key
     * @param index>=0时候 0表头，1第二个元素
     * index<0时候 -1表尾，-2倒数第二个元素
     * @return
     */
    public Object listGetIndex(String key,long index){
    	try {
			return redisTemplate.opsForList().index(key, index);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return null;
		}
    }
    
    /**
     * 把list放入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean listSet(String key,Object value){
    	try {
			redisTemplate.opsForList().rightPush(key, value);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * list放入缓存
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean listSet(String key,Object value,long time){
    	try {
			redisTemplate.opsForList().rightPush(key, value);
			if(time>0){
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 把list放入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean listSet(String key,List<Object> value){
    	try {
			redisTemplate.opsForList().rightPushAll(key, value);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * list放入缓存
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean listSet(String key,List<Object> value,long time){
    	try {
			redisTemplate.opsForList().rightPushAll(key, value);
			if(time>0){
				expire(key, time);
			}
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 根据索引更新list中的某个数据
     * @param key
     * @param index
     * @param value
     * @return
     */
    public boolean listUpdateByIndex(String key,long index,Object value){
    	try {
			redisTemplate.opsForList().set(key, index, value);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return false;
		}
    }
    
    /**
     * 移除n个值为value的key
     * @param key
     * @param count
     * @param value
     * @return
     */
    public long listRemove(String key,long count,Object value){
    	try {
			Long remove=redisTemplate.opsForList().remove(key, count, value);
			return remove;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
    }
}
